home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / perl / os2perl / walk.c < prev    next >
C/C++ Source or Header  |  1991-06-11  |  50KB  |  2,061 lines

  1. /* $RCSfile: walk.c,v $$Revision: 4.0.1.1 $$Date: 91/06/07 12:22:04 $
  2.  *
  3.  *    Copyright (c) 1991, Larry Wall
  4.  *
  5.  *    You may distribute under the terms of either the GNU General Public
  6.  *    License or the Artistic License, as specified in the README file.
  7.  *
  8.  * $Log:    walk.c,v $
  9.  * Revision 4.0.1.1  91/06/07  12:22:04  lwall
  10.  * patch4: new copyright notice
  11.  * patch4: a2p didn't correctly implement -n switch
  12.  *
  13.  * Revision 4.0  91/03/20  01:58:36  lwall
  14.  * 4.0 baseline.
  15.  *
  16.  */
  17.  
  18. #include "handy.h"
  19. #include "EXTERN.h"
  20. #include "util.h"
  21. #include "a2p.h"
  22.  
  23. bool exitval = FALSE;
  24. bool realexit = FALSE;
  25. bool saw_getline = FALSE;
  26. bool subretnum = FALSE;
  27. bool saw_FNR = FALSE;
  28. bool saw_argv0 = FALSE;
  29. bool saw_fh = FALSE;
  30. int maxtmp = 0;
  31. char *lparen;
  32. char *rparen;
  33. STR *subs;
  34. STR *curargs = Nullstr;
  35.  
  36. STR *
  37. walk(useval,level,node,numericptr,minprec)
  38. int useval;
  39. int level;
  40. register int node;
  41. int *numericptr;
  42. int minprec;            /* minimum precedence without parens */
  43. {
  44.     register int len;
  45.     register STR *str;
  46.     register int type;
  47.     register int i;
  48.     register STR *tmpstr;
  49.     STR *tmp2str;
  50.     STR *tmp3str;
  51.     char *t;
  52.     char *d, *s;
  53.     int numarg;
  54.     int numeric = FALSE;
  55.     STR *fstr;
  56.     int prec = P_MAX;        /* assume no parens needed */
  57.     char *index();
  58.  
  59.     if (!node) {
  60.     *numericptr = 0;
  61.     return str_make("");
  62.     }
  63.     type = ops[node].ival;
  64.     len = type >> 8;
  65.     type &= 255;
  66.     switch (type) {
  67.     case OPROG:
  68.     arymax = 0;
  69.     if (namelist) {
  70.         while (isalpha(*namelist)) {
  71.         for (d = tokenbuf,s=namelist;
  72.           isalpha(*s) || isdigit(*s) || *s == '_';
  73.           *d++ = *s++) ;
  74.         *d = '\0';
  75.         while (*s && !isalpha(*s)) s++;
  76.         namelist = s;
  77.         nameary[++arymax] = savestr(tokenbuf);
  78.         }
  79.     }
  80.     if (maxfld < arymax)
  81.         maxfld = arymax;
  82.     opens = str_new(0);
  83.     subs = str_new(0);
  84.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  85.     if (do_split && need_entire && !absmaxfld)
  86.         split_to_array = TRUE;
  87.     if (do_split && split_to_array)
  88.         set_array_base = TRUE;
  89.     if (set_array_base) {
  90.         str_cat(str,"$[ = 1;\t\t\t# set array base to 1\n");
  91.     }
  92.     if (fswitch && !const_FS)
  93.         const_FS = fswitch;
  94.     if (saw_FS > 1 || saw_RS)
  95.         const_FS = 0;
  96.     if (saw_ORS && need_entire)
  97.         do_chop = TRUE;
  98.     if (fswitch) {
  99.         str_cat(str,"$FS = '");
  100.         if (index("*+?.[]()|^$\\",fswitch))
  101.         str_cat(str,"\\");
  102.         sprintf(tokenbuf,"%c",fswitch);
  103.         str_cat(str,tokenbuf);
  104.         str_cat(str,"';\t\t# field separator from -F switch\n");
  105.     }
  106.     else if (saw_FS && !const_FS) {
  107.         str_cat(str,"$FS = ' ';\t\t# set field separator\n");
  108.     }
  109.     if (saw_OFS) {
  110.         str_cat(str,"$, = ' ';\t\t# set output field separator\n");
  111.     }
  112.     if (saw_ORS) {
  113.         str_cat(str,"$\\ = \"\\n\";\t\t# set output record separator\n");
  114.     }
  115.     if (saw_argv0) {
  116.         str_cat(str,"$ARGV0 = $0;\t\t# remember what we ran as\n");
  117.     }
  118.     if (str->str_cur > 20)
  119.         str_cat(str,"\n");
  120.     if (ops[node+2].ival) {
  121.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  122.         str_free(fstr);
  123.         str_cat(str,"\n\n");
  124.     }
  125.     fstr = walk(0,level+1,ops[node+3].ival,&numarg,P_MIN);
  126.     if (*fstr->str_ptr) {
  127.         if (saw_line_op)
  128.         str_cat(str,"line: ");
  129.         str_cat(str,"while (<>) {\n");
  130.         tab(str,++level);
  131.         if (saw_FS && !const_FS)
  132.         do_chop = TRUE;
  133.         if (do_chop) {
  134.         str_cat(str,"chop;\t# strip record separator\n");
  135.         tab(str,level);
  136.         }
  137.         if (do_split)
  138.         emit_split(str,level);
  139.         str_scat(str,fstr);
  140.         str_free(fstr);
  141.         fixtab(str,--level);
  142.         str_cat(str,"}\n");
  143.         if (saw_FNR)
  144.         str_cat(str,"continue {\n    $FNRbase = $. if eof;\n}\n");
  145.     }
  146.     else
  147.         str_cat(str,"while (<>) { }        # (no line actions)\n");
  148.     if (ops[node+4].ival) {
  149.         realexit = TRUE;
  150.         str_cat(str,"\n");
  151.         tab(str,level);
  152.         str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
  153.         str_free(fstr);
  154.         str_cat(str,"\n");
  155.     }
  156.     if (exitval)
  157.         str_cat(str,"exit $ExitValue;\n");
  158.     if (subs->str_ptr) {
  159.         str_cat(str,"\n");
  160.         str_scat(str,subs);
  161.     }
  162.     if (saw_getline) {
  163.         for (len = 0; len < 4; len++) {
  164.         if (saw_getline & (1 << len)) {
  165.             sprintf(tokenbuf,"\nsub Getline%d {\n",len);
  166.             str_cat(str, tokenbuf);
  167.             if (len & 2) {
  168.             if (do_fancy_opens)
  169.                 str_cat(str,"    &Pick('',@_);\n");
  170.             else
  171.                 str_cat(str,"    ($fh) = @_;\n");
  172.             }
  173.             else {
  174.             if (saw_FNR)
  175.                 str_cat(str,"    $FNRbase = $. if eof;\n");
  176.             }
  177.             if (len & 1)
  178.             str_cat(str,"    local($_);\n");
  179.             if (len & 2)
  180.             str_cat(str,
  181.               "    if ($getline_ok = (($_ = <$fh>) ne ''))");
  182.             else
  183.             str_cat(str,
  184.               "    if ($getline_ok = (($_ = <>) ne ''))");
  185.             str_cat(str, " {\n");
  186.             level += 2;
  187.             tab(str,level);
  188.             i = 0;
  189.             if (do_chop) {
  190.             i++;
  191.             str_cat(str,"chop;\t# strip record separator\n");
  192.             tab(str,level);
  193.             }
  194.             if (do_split && !(len & 1)) {
  195.             i++;
  196.             emit_split(str,level);
  197.             }
  198.             if (!i)
  199.             str_cat(str,";\n");
  200.             fixtab(str,--level);
  201.             str_cat(str,"}\n    $_;\n}\n");
  202.             --level;
  203.         }
  204.         }
  205.     }
  206.     if (do_fancy_opens) {
  207.         str_cat(str,"\n\
  208. sub Pick {\n\
  209.     local($mode,$name,$pipe) = @_;\n\
  210.     $fh = $opened{$name};\n\
  211.     if (!$fh) {\n\
  212.     $fh = $opened{$name} = 'fh_' . ($nextfh++ + 0);\n\
  213.     open($fh,$mode.$name.$pipe);\n\
  214.     }\n\
  215. }\n\
  216. ");
  217.     }
  218.     break;
  219.     case OHUNKS:
  220.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  221.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  222.     str_free(fstr);
  223.     if (len == 3) {
  224.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  225.         str_free(fstr);
  226.     }
  227.     else {
  228.     }
  229.     break;
  230.     case ORANGE:
  231.     prec = P_DOTDOT;
  232.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  233.     str_cat(str," .. ");
  234.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  235.     str_free(fstr);
  236.     break;
  237.     case OPAT:
  238.     goto def;
  239.     case OREGEX:
  240.     str = str_new(0);
  241.     str_set(str,"/");
  242.     tmpstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  243.     /* translate \nnn to [\nnn] */
  244.     for (s = tmpstr->str_ptr, d = tokenbuf; *s; s++, d++) {
  245.         if (*s == '\\' && isdigit(s[1]) && isdigit(s[2]) && isdigit(s[3])){
  246.         *d++ = '[';
  247.         *d++ = *s++;
  248.         *d++ = *s++;
  249.         *d++ = *s++;
  250.         *d++ = *s;
  251.         *d = ']';
  252.         }
  253.         else
  254.         *d = *s;
  255.     }
  256.     *d = '\0';
  257.     for (d=tokenbuf; *d; d++)
  258.         *d += 128;
  259.     str_cat(str,tokenbuf);
  260.     str_free(tmpstr);
  261.     str_cat(str,"/");
  262.     break;
  263.     case OHUNK:
  264.     if (len == 1) {
  265.         str = str_new(0);
  266.         str = walk(0,level,oper1(OPRINT,0),&numarg,P_MIN);
  267.         str_cat(str," if ");
  268.         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  269.         str_free(fstr);
  270.         str_cat(str,";");
  271.     }
  272.     else {
  273.         tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  274.         if (*tmpstr->str_ptr) {
  275.         str = str_new(0);
  276.         str_set(str,"if (");
  277.         str_scat(str,tmpstr);
  278.         str_cat(str,") {\n");
  279.         tab(str,++level);
  280.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  281.         str_free(fstr);
  282.         fixtab(str,--level);
  283.         str_cat(str,"}\n");
  284.         tab(str,level);
  285.         }
  286.         else {
  287.         str = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
  288.         }
  289.     }
  290.     break;
  291.     case OPPAREN:
  292.     str = str_new(0);
  293.     str_set(str,"(");
  294.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  295.     str_free(fstr);
  296.     str_cat(str,")");
  297.     break;
  298.     case OPANDAND:
  299.     prec = P_ANDAND;
  300.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  301.     str_cat(str," && ");
  302.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  303.     str_free(fstr);
  304.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  305.     str_free(fstr);
  306.     break;
  307.     case OPOROR:
  308.     prec = P_OROR;
  309.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  310.     str_cat(str," || ");
  311.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  312.     str_free(fstr);
  313.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  314.     str_free(fstr);
  315.     break;
  316.     case OPNOT:
  317.     prec = P_UNARY;
  318.     str = str_new(0);
  319.     str_set(str,"!");
  320.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  321.     str_free(fstr);
  322.     break;
  323.     case OCOND:
  324.     prec = P_COND;
  325.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  326.     str_cat(str," ? ");
  327.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  328.     str_free(fstr);
  329.     str_cat(str," : ");
  330.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  331.     str_free(fstr);
  332.     break;
  333.     case OCPAREN:
  334.     str = str_new(0);
  335.     str_set(str,"(");
  336.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  337.     str_free(fstr);
  338.     numeric |= numarg;
  339.     str_cat(str,")");
  340.     break;
  341.     case OCANDAND:
  342.     prec = P_ANDAND;
  343.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  344.     numeric = 1;
  345.     str_cat(str," && ");
  346.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  347.     str_free(fstr);
  348.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  349.     str_free(fstr);
  350.     break;
  351.     case OCOROR:
  352.     prec = P_OROR;
  353.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  354.     numeric = 1;
  355.     str_cat(str," || ");
  356.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  357.     str_free(fstr);
  358.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  359.     str_free(fstr);
  360.     break;
  361.     case OCNOT:
  362.     prec = P_UNARY;
  363.     str = str_new(0);
  364.     str_set(str,"!");
  365.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  366.     str_free(fstr);
  367.     numeric = 1;
  368.     break;
  369.     case ORELOP:
  370.     prec = P_REL;
  371.     str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
  372.     numeric |= numarg;
  373.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  374.     tmp2str = walk(1,level,ops[node+3].ival,&numarg,prec+1);
  375.     numeric |= numarg;
  376.     if (!numeric ||
  377.      (!numarg && (*tmp2str->str_ptr == '"' || *tmp2str->str_ptr == '\''))) {
  378.         t = tmpstr->str_ptr;
  379.         if (strEQ(t,"=="))
  380.         str_set(tmpstr,"eq");
  381.         else if (strEQ(t,"!="))
  382.         str_set(tmpstr,"ne");
  383.         else if (strEQ(t,"<"))
  384.         str_set(tmpstr,"lt");
  385.         else if (strEQ(t,"<="))
  386.         str_set(tmpstr,"le");
  387.         else if (strEQ(t,">"))
  388.         str_set(tmpstr,"gt");
  389.         else if (strEQ(t,">="))
  390.         str_set(tmpstr,"ge");
  391.         if (!index(tmpstr->str_ptr,'\'') && !index(tmpstr->str_ptr,'"') &&
  392.           !index(tmp2str->str_ptr,'\'') && !index(tmp2str->str_ptr,'"') )
  393.         numeric |= 2;
  394.     }
  395.     if (numeric & 2) {
  396.         if (numeric & 1)        /* numeric is very good guess */
  397.         str_cat(str," ");
  398.         else
  399.         str_cat(str,"\377");
  400.         numeric = 1;
  401.     }
  402.     else
  403.         str_cat(str," ");
  404.     str_scat(str,tmpstr);
  405.     str_free(tmpstr);
  406.     str_cat(str," ");
  407.     str_scat(str,tmp2str);
  408.     str_free(tmp2str);
  409.     numeric = 1;
  410.     break;
  411.     case ORPAREN:
  412.     str = str_new(0);
  413.     str_set(str,"(");
  414.     str_scat(str,fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  415.     str_free(fstr);
  416.     numeric |= numarg;
  417.     str_cat(str,")");
  418.     break;
  419.     case OMATCHOP:
  420.     prec = P_MATCH;
  421.     str = walk(1,level,ops[node+2].ival,&numarg,prec+1);
  422.     str_cat(str," ");
  423.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  424.     if (strEQ(tmpstr->str_ptr,"~"))
  425.         str_cat(str,"=~");
  426.     else {
  427.         str_scat(str,tmpstr);
  428.         str_free(tmpstr);
  429.     }
  430.     str_cat(str," ");
  431.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  432.     str_free(fstr);
  433.     numeric = 1;
  434.     break;
  435.     case OMPAREN:
  436.     str = str_new(0);
  437.     str_set(str,"(");
  438.     str_scat(str,
  439.       fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  440.     str_free(fstr);
  441.     numeric |= numarg;
  442.     str_cat(str,")");
  443.     break;
  444.     case OCONCAT:
  445.     prec = P_ADD;
  446.     type = ops[ops[node+1].ival].ival & 255;
  447.     str = walk(1,level,ops[node+1].ival,&numarg,prec+(type != OCONCAT));
  448.     str_cat(str," . ");
  449.     type = ops[ops[node+2].ival].ival & 255;
  450.     str_scat(str,
  451.       fstr=walk(1,level,ops[node+2].ival,&numarg,prec+(type != OCONCAT)));
  452.     str_free(fstr);
  453.     break;
  454.     case OASSIGN:
  455.     prec = P_ASSIGN;
  456.     str = walk(0,level,ops[node+2].ival,&numarg,prec+1);
  457.     str_cat(str," ");
  458.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  459.     str_scat(str,tmpstr);
  460.     if (str_len(tmpstr) > 1)
  461.         numeric = 1;
  462.     str_free(tmpstr);
  463.     str_cat(str," ");
  464.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec));
  465.     str_free(fstr);
  466.     numeric |= numarg;
  467.     break;
  468.     case OADD:
  469.     prec = P_ADD;
  470.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  471.     str_cat(str," + ");
  472.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  473.     str_free(fstr);
  474.     numeric = 1;
  475.     break;
  476.     case OSUBTRACT:
  477.     prec = P_ADD;
  478.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  479.     str_cat(str," - ");
  480.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  481.     str_free(fstr);
  482.     numeric = 1;
  483.     break;
  484.     case OMULT:
  485.     prec = P_MUL;
  486.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  487.     str_cat(str," * ");
  488.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  489.     str_free(fstr);
  490.     numeric = 1;
  491.     break;
  492.     case ODIV:
  493.     prec = P_MUL;
  494.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  495.     str_cat(str," / ");
  496.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  497.     str_free(fstr);
  498.     numeric = 1;
  499.     break;
  500.     case OPOW:
  501.     prec = P_POW;
  502.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  503.     str_cat(str," ** ");
  504.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec));
  505.     str_free(fstr);
  506.     numeric = 1;
  507.     break;
  508.     case OMOD:
  509.     prec = P_MUL;
  510.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  511.     str_cat(str," % ");
  512.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,prec+1));
  513.     str_free(fstr);
  514.     numeric = 1;
  515.     break;
  516.     case OPOSTINCR:
  517.     prec = P_AUTO;
  518.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  519.     str_cat(str,"++");
  520.     numeric = 1;
  521.     break;
  522.     case OPOSTDECR:
  523.     prec = P_AUTO;
  524.     str = walk(1,level,ops[node+1].ival,&numarg,prec+1);
  525.     str_cat(str,"--");
  526.     numeric = 1;
  527.     break;
  528.     case OPREINCR:
  529.     prec = P_AUTO;
  530.     str = str_new(0);
  531.     str_set(str,"++");
  532.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  533.     str_free(fstr);
  534.     numeric = 1;
  535.     break;
  536.     case OPREDECR:
  537.     prec = P_AUTO;
  538.     str = str_new(0);
  539.     str_set(str,"--");
  540.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  541.     str_free(fstr);
  542.     numeric = 1;
  543.     break;
  544.     case OUMINUS:
  545.     prec = P_UNARY;
  546.     str = str_new(0);
  547.     str_set(str,"-");
  548.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,prec));
  549.     str_free(fstr);
  550.     numeric = 1;
  551.     break;
  552.     case OUPLUS:
  553.     numeric = 1;
  554.     goto def;
  555.     case OPAREN:
  556.     str = str_new(0);
  557.     str_set(str,"(");
  558.     str_scat(str,
  559.       fstr=walk(useval != 0,level,ops[node+1].ival,&numarg,P_MIN));
  560.     str_free(fstr);
  561.     str_cat(str,")");
  562.     numeric |= numarg;
  563.     break;
  564.     case OGETLINE:
  565.     str = str_new(0);
  566.     if (useval)
  567.         str_cat(str,"(");
  568.     if (len > 0) {
  569.         str_cat(str,"$");
  570.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  571.         if (!*fstr->str_ptr) {
  572.         str_cat(str,"_");
  573.         len = 2;        /* a legal fiction */
  574.         }
  575.         str_free(fstr);
  576.     }
  577.     else
  578.         str_cat(str,"$_");
  579.     if (len > 1) {
  580.         tmpstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN);
  581.         fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  582.         if (!do_fancy_opens) {
  583.         t = tmpstr->str_ptr;
  584.         if (*t == '"' || *t == '\'')
  585.             t = cpytill(tokenbuf,t+1,*t);
  586.         else
  587.             fatal("Internal error: OGETLINE %s", t);
  588.         d = savestr(t);
  589.         s = savestr(tokenbuf);
  590.         for (t = tokenbuf; *t; t++) {
  591.             *t &= 127;
  592.             if (islower(*t))
  593.             *t = toupper(*t);
  594.             if (!isalpha(*t) && !isdigit(*t))
  595.             *t = '_';
  596.         }
  597.         if (!index(tokenbuf,'_'))
  598.             strcpy(t,"_FH");
  599.         tmp3str = hfetch(symtab,tokenbuf);
  600.         if (!tmp3str) {
  601.             do_opens = TRUE;
  602.             str_cat(opens,"open(");
  603.             str_cat(opens,tokenbuf);
  604.             str_cat(opens,", ");
  605.             d[1] = '\0';
  606.             str_cat(opens,d);
  607.             str_cat(opens,tmpstr->str_ptr+1);
  608.             opens->str_cur--;
  609.             if (*fstr->str_ptr == '|')
  610.             str_cat(opens,"|");
  611.             str_cat(opens,d);
  612.             if (*fstr->str_ptr == '|')
  613.             str_cat(opens,") || die 'Cannot pipe from \"");
  614.             else
  615.             str_cat(opens,") || die 'Cannot open file \"");
  616.             if (*d == '"')
  617.             str_cat(opens,"'.\"");
  618.             str_cat(opens,s);
  619.             if (*d == '"')
  620.             str_cat(opens,"\".'");
  621.             str_cat(opens,"\".';\n");
  622.             hstore(symtab,tokenbuf,str_make("x"));
  623.         }
  624.         safefree(s);
  625.         safefree(d);
  626.         str_set(tmpstr,"'");
  627.         str_cat(tmpstr,tokenbuf);
  628.         str_cat(tmpstr,"'");
  629.         }
  630.         if (*fstr->str_ptr == '|')
  631.         str_cat(tmpstr,", '|'");
  632.         str_free(fstr);
  633.     }
  634.     else
  635.         tmpstr = str_make("");
  636.     sprintf(tokenbuf," = &Getline%d(%s)",len,tmpstr->str_ptr);
  637.     str_cat(str,tokenbuf);
  638.     str_free(tmpstr);
  639.     if (useval)
  640.         str_cat(str,",$getline_ok)");
  641.     saw_getline |= 1 << len;
  642.     break;
  643.     case OSPRINTF:
  644.     str = str_new(0);
  645.     str_set(str,"sprintf(");
  646.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  647.     str_free(fstr);
  648.     str_cat(str,")");
  649.     break;
  650.     case OSUBSTR:
  651.     str = str_new(0);
  652.     str_set(str,"substr(");
  653.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  654.     str_free(fstr);
  655.     str_cat(str,", ");
  656.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
  657.     str_free(fstr);
  658.     str_cat(str,", ");
  659.     if (len == 3) {
  660.         str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1));
  661.         str_free(fstr);
  662.     }
  663.     else
  664.         str_cat(str,"999999");
  665.     str_cat(str,")");
  666.     break;
  667.     case OSTRING:
  668.     str = str_new(0);
  669.     str_set(str,ops[node+1].cval);
  670.     break;
  671.     case OSPLIT:
  672.     str = str_new(0);
  673.     numeric = 1;
  674.     tmpstr = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  675.     if (useval)
  676.         str_set(str,"(@");
  677.     else
  678.         str_set(str,"@");
  679.     str_scat(str,tmpstr);
  680.     str_cat(str," = split(");
  681.     if (len == 3) {
  682.         fstr = walk(1,level,ops[node+3].ival,&numarg,P_COMMA+1);
  683.         if (str_len(fstr) == 3 && *fstr->str_ptr == '\'') {
  684.         i = fstr->str_ptr[1] & 127;
  685.         if (index("*+?.[]()|^$\\",i))
  686.             sprintf(tokenbuf,"/\\%c/",i);
  687.         else if (i == ' ')
  688.             sprintf(tokenbuf,"' '");
  689.         else
  690.             sprintf(tokenbuf,"/%c/",i);
  691.         str_cat(str,tokenbuf);
  692.         }
  693.         else
  694.         str_scat(str,fstr);
  695.         str_free(fstr);
  696.     }
  697.     else if (const_FS) {
  698.         sprintf(tokenbuf,"/[%c\\n]/",const_FS);
  699.         str_cat(str,tokenbuf);
  700.     }
  701.     else if (saw_FS)
  702.         str_cat(str,"$FS");
  703.     else
  704.         str_cat(str,"' '");
  705.     str_cat(str,", ");
  706.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  707.     str_free(fstr);
  708.     str_cat(str,", 9999)");
  709.     if (useval) {
  710.         str_cat(str,")");
  711.     }
  712.     str_free(tmpstr);
  713.     break;
  714.     case OINDEX:
  715.     str = str_new(0);
  716.     str_set(str,"index(");
  717.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_COMMA+1));
  718.     str_free(fstr);
  719.     str_cat(str,", ");
  720.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_COMMA+1));
  721.     str_free(fstr);
  722.     str_cat(str,")");
  723.     numeric = 1;
  724.     break;
  725.     case OMATCH:
  726.     str = str_new(0);
  727.     prec = P_ANDAND;
  728.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MATCH+1));
  729.     str_free(fstr);
  730.     str_cat(str," =~ ");
  731.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MATCH+1));
  732.     str_free(fstr);
  733.     str_cat(str," && ($RLENGTH = length($&), $RSTART = length($`)+1)");
  734.     numeric = 1;
  735.     break;
  736.     case OUSERDEF:
  737.     str = str_new(0);
  738.     subretnum = FALSE;
  739.     fstr=walk(1,level-1,ops[node+2].ival,&numarg,P_MIN);
  740.     curargs = str_new(0);
  741.     str_sset(curargs,fstr);
  742.     str_cat(curargs,",");
  743.     tmp2str=walk(1,level,ops[node+5].ival,&numarg,P_MIN);
  744.     str_free(curargs);
  745.     curargs = Nullstr;
  746.     level--;
  747.     subretnum |= numarg;
  748.     s = Nullch;
  749.     t = tmp2str->str_ptr;
  750.     while (t = instr(t,"return "))
  751.         s = t++;
  752.     if (s) {
  753.         i = 0;
  754.         for (t = s+7; *t; t++) {
  755.         if (*t == ';' || *t == '}')
  756.             i++;
  757.         }
  758.         if (i == 1) {
  759.         strcpy(s,s+7);
  760.         tmp2str->str_cur -= 7;
  761.         }
  762.     }
  763.     str_set(str,"\n");
  764.     tab(str,level);
  765.     str_cat(str,"sub ");
  766.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  767.     str_cat(str," {\n");
  768.     tab(str,++level);
  769.     if (fstr->str_cur) {
  770.         str_cat(str,"local(");
  771.         str_scat(str,fstr);
  772.         str_cat(str,") = @_;");
  773.     }
  774.     str_free(fstr);
  775.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
  776.     str_free(fstr);
  777.     fixtab(str,level);
  778.     str_scat(str,fstr=walk(1,level,ops[node+4].ival,&numarg,P_MIN));
  779.     str_free(fstr);
  780.     fixtab(str,level);
  781.     str_scat(str,tmp2str);
  782.     str_free(tmp2str);
  783.     fixtab(str,--level);
  784.     str_cat(str,"}\n");
  785.     tab(str,level);
  786.     str_scat(subs,str);
  787.     str_set(str,"");
  788.     str_cat(tmpstr,"(");
  789.     tmp2str = str_new(0);
  790.     if (subretnum)
  791.         str_set(tmp2str,"1");
  792.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  793.     str_free(tmpstr);
  794.     level++;
  795.     break;
  796.     case ORETURN:
  797.     str = str_new(0);
  798.     if (len > 0) {
  799.         str_cat(str,"return ");
  800.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_UNI+1));
  801.         str_free(fstr);
  802.         if (numarg)
  803.         subretnum = TRUE;
  804.     }
  805.     else
  806.         str_cat(str,"return");
  807.     break;
  808.     case OUSERFUN:
  809.     str = str_new(0);
  810.     str_set(str,"&");
  811.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  812.     str_free(fstr);
  813.     str_cat(str,"(");
  814.     tmpstr = hfetch(symtab,str->str_ptr+3);
  815.     if (tmpstr && tmpstr->str_ptr)
  816.         numeric |= atoi(tmpstr->str_ptr);
  817.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  818.     str_free(fstr);
  819.     str_cat(str,")");
  820.     break;
  821.     case OGSUB:
  822.     case OSUB:
  823.     if (type == OGSUB)
  824.         s = "g";
  825.     else
  826.         s = "";
  827.     str = str_new(0);
  828.     tmpstr = str_new(0);
  829.     i = 0;
  830.     if (len == 3) {
  831.         tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MATCH+1);
  832.         if (strNE(tmpstr->str_ptr,"$_")) {
  833.         str_cat(tmpstr, " =~ s");
  834.         i++;
  835.         }
  836.         else
  837.         str_set(tmpstr, "s");
  838.     }
  839.     else
  840.         str_set(tmpstr, "s");
  841.     type = ops[ops[node+2].ival].ival;
  842.     len = type >> 8;
  843.     type &= 255;
  844.     tmp3str = str_new(0);
  845.     if (type == OSTR) {
  846.         tmp2str=walk(1,level,ops[ops[node+2].ival+1].ival,&numarg,P_MIN);
  847.         for (t = tmp2str->str_ptr, d=tokenbuf; *t; d++,t++) {
  848.         if (*t == '&')
  849.             *d++ = '$' + 128;
  850.         else if (*t == '$')
  851.             *d++ = '\\' + 128;
  852.         *d = *t + 128;
  853.         }
  854.         *d = '\0';
  855.         str_set(tmp2str,tokenbuf);
  856.     }
  857.     else {
  858.         tmp2str=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  859.         str_set(tmp3str,"($s_ = '\"'.(");
  860.         str_scat(tmp3str,tmp2str);
  861.         str_cat(tmp3str,").'\"') =~ s/&/\\$&/g, ");
  862.         str_set(tmp2str,"eval $s_");
  863.         s = (*s == 'g' ? "ge" : "e");
  864.         i++;
  865.     }
  866.     type = ops[ops[node+1].ival].ival;
  867.     len = type >> 8;
  868.     type &= 255;
  869.     fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  870.     if (type == OREGEX) {
  871.         if (useval && i)
  872.         str_cat(str,"(");
  873.         str_scat(str,tmp3str);
  874.         str_scat(str,tmpstr);
  875.         str_scat(str,fstr);
  876.         str_scat(str,tmp2str);
  877.         str_cat(str,"/");
  878.         str_cat(str,s);
  879.     }
  880.     else if ((type == OFLD && !split_to_array) || (type == OVAR && len == 1)) {
  881.         if (useval && i)
  882.         str_cat(str,"(");
  883.         str_scat(str,tmp3str);
  884.         str_scat(str,tmpstr);
  885.         str_cat(str,"/");
  886.         str_scat(str,fstr);
  887.         str_cat(str,"/");
  888.         str_scat(str,tmp2str);
  889.         str_cat(str,"/");
  890.         str_cat(str,s);
  891.     }
  892.     else {
  893.         i++;
  894.         if (useval)
  895.         str_cat(str,"(");
  896.         str_cat(str,"$s = ");
  897.         str_scat(str,fstr);
  898.         str_cat(str,", ");
  899.         str_scat(str,tmp3str);
  900.         str_scat(str,tmpstr);
  901.         str_cat(str,"/$s/");
  902.         str_scat(str,tmp2str);
  903.         str_cat(str,"/");
  904.         str_cat(str,s);
  905.     }
  906.     if (useval && i)
  907.         str_cat(str,")");
  908.     str_free(fstr);
  909.     str_free(tmpstr);
  910.     str_free(tmp2str);
  911.     str_free(tmp3str);
  912.     numeric = 1;
  913.     break;
  914.     case ONUM:
  915.     str = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  916.     numeric = 1;
  917.     break;
  918.     case OSTR:
  919.     tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  920.     s = "'";
  921.     for (t = tmpstr->str_ptr, d=tokenbuf; *t; d++,t++) {
  922.         if (*t == '\'')
  923.         s = "\"";
  924.         else if (*t == '\\') {
  925.         s = "\"";
  926.         *d++ = *t++ + 128;
  927.         switch (*t) {
  928.         case '\\': case '"': case 'n': case 't': case '$':
  929.             break;
  930.         default:    /* hide this from perl */
  931.             *d++ = '\\' + 128;
  932.         }
  933.         }
  934.         *d = *t + 128;
  935.     }
  936.     *d = '\0';
  937.     str = str_new(0);
  938.     str_set(str,s);
  939.     str_cat(str,tokenbuf);
  940.     str_free(tmpstr);
  941.     str_cat(str,s);
  942.     break;
  943.     case ODEFINED:
  944.     prec = P_UNI;
  945.     str = str_new(0);
  946.     str_set(str,"defined $");
  947.     goto addvar;
  948.     case ODELETE:
  949.     str = str_new(0);
  950.     str_set(str,"delete $");
  951.     goto addvar;
  952.     case OSTAR:
  953.     str = str_new(0);
  954.     str_set(str,"*");
  955.     goto addvar;
  956.     case OVAR:
  957.     str = str_new(0);
  958.     str_set(str,"$");
  959.       addvar:
  960.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  961.     if (len == 1) {
  962.         tmp2str = hfetch(symtab,tmpstr->str_ptr);
  963.         if (tmp2str && atoi(tmp2str->str_ptr))
  964.         numeric = 2;
  965.         if (strEQ(str->str_ptr,"$FNR")) {
  966.         numeric = 1;
  967.         saw_FNR++;
  968.         str_set(str,"($.-$FNRbase)");
  969.         }
  970.         else if (strEQ(str->str_ptr,"$NR")) {
  971.         numeric = 1;
  972.         str_set(str,"$.");
  973.         }
  974.         else if (strEQ(str->str_ptr,"$NF")) {
  975.         numeric = 1;
  976.         str_set(str,"$#Fld");
  977.         }
  978.         else if (strEQ(str->str_ptr,"$0"))
  979.         str_set(str,"$_");
  980.         else if (strEQ(str->str_ptr,"$ARGC"))
  981.         str_set(str,"($#ARGV+1)");
  982.     }
  983.     else {
  984. #ifdef NOTDEF
  985.         if (curargs) {
  986.         sprintf(tokenbuf,"$%s,",tmpstr->str_ptr);
  987.     ???    if (instr(curargs->str_ptr,tokenbuf))
  988.             str_cat(str,"\377");    /* can't translate yet */
  989.         }
  990. #endif
  991.         str_cat(tmpstr,"[]");
  992.         tmp2str = hfetch(symtab,tmpstr->str_ptr);
  993.         if (tmp2str && atoi(tmp2str->str_ptr))
  994.         str_cat(str,"[");
  995.         else
  996.         str_cat(str,"{");
  997.         str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  998.         str_free(fstr);
  999.         if (strEQ(str->str_ptr,"$ARGV[0")) {
  1000.         str_set(str,"$ARGV0");
  1001.         saw_argv0++;
  1002.         }
  1003.         else {
  1004.         if (tmp2str && atoi(tmp2str->str_ptr))
  1005.             strcpy(tokenbuf,"]");
  1006.         else
  1007.             strcpy(tokenbuf,"}");
  1008.         *tokenbuf += 128;
  1009.         str_cat(str,tokenbuf);
  1010.         }
  1011.     }
  1012.     str_free(tmpstr);
  1013.     break;
  1014.     case OFLD:
  1015.     str = str_new(0);
  1016.     if (split_to_array) {
  1017.         str_set(str,"$Fld");
  1018.         str_cat(str,"[");
  1019.         str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1020.         str_free(fstr);
  1021.         str_cat(str,"]");
  1022.     }
  1023.     else {
  1024.         i = atoi(walk(1,level,ops[node+1].ival,&numarg,P_MIN)->str_ptr);
  1025.         if (i <= arymax)
  1026.         sprintf(tokenbuf,"$%s",nameary[i]);
  1027.         else
  1028.         sprintf(tokenbuf,"$Fld%d",i);
  1029.         str_set(str,tokenbuf);
  1030.     }
  1031.     break;
  1032.     case OVFLD:
  1033.     str = str_new(0);
  1034.     str_set(str,"$Fld[");
  1035.     i = ops[node+1].ival;
  1036.     if ((ops[i].ival & 255) == OPAREN)
  1037.         i = ops[i+1].ival;
  1038.     tmpstr=walk(1,level,i,&numarg,P_MIN);
  1039.     str_scat(str,tmpstr);
  1040.     str_free(tmpstr);
  1041.     str_cat(str,"]");
  1042.     break;
  1043.     case OJUNK:
  1044.     goto def;
  1045.     case OSNEWLINE:
  1046.     str = str_new(2);
  1047.     str_set(str,";\n");
  1048.     tab(str,level);
  1049.     break;
  1050.     case ONEWLINE:
  1051.     str = str_new(1);
  1052.     str_set(str,"\n");
  1053.     tab(str,level);
  1054.     break;
  1055.     case OSCOMMENT:
  1056.     str = str_new(0);
  1057.     str_set(str,";");
  1058.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1059.     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
  1060.         *s += 128;
  1061.     str_scat(str,tmpstr);
  1062.     str_free(tmpstr);
  1063.     tab(str,level);
  1064.     break;
  1065.     case OCOMMENT:
  1066.     str = str_new(0);
  1067.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1068.     for (s = tmpstr->str_ptr; *s && *s != '\n'; s++)
  1069.         *s += 128;
  1070.     str_scat(str,tmpstr);
  1071.     str_free(tmpstr);
  1072.     tab(str,level);
  1073.     break;
  1074.     case OCOMMA:
  1075.     prec = P_COMMA;
  1076.     str = walk(1,level,ops[node+1].ival,&numarg,prec);
  1077.     str_cat(str,", ");
  1078.     str_scat(str,fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN));
  1079.     str_free(fstr);
  1080.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,prec+1));
  1081.     str_free(fstr);
  1082.     break;
  1083.     case OSEMICOLON:
  1084.     str = str_new(1);
  1085.     str_set(str,";\n");
  1086.     tab(str,level);
  1087.     break;
  1088.     case OSTATES:
  1089.     str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1090.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1091.     str_free(fstr);
  1092.     break;
  1093.     case OSTATE:
  1094.     str = str_new(0);
  1095.     if (len >= 1) {
  1096.         str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  1097.         str_free(fstr);
  1098.         if (len >= 2) {
  1099.         tmpstr = walk(0,level,ops[node+2].ival,&numarg,P_MIN);
  1100.         if (*tmpstr->str_ptr == ';') {
  1101.             addsemi(str);
  1102.             str_cat(str,tmpstr->str_ptr+1);
  1103.         }
  1104.         str_free(tmpstr);
  1105.         }
  1106.     }
  1107.     break;
  1108.     case OCLOSE:
  1109.     str = str_make("close(");
  1110.     tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  1111.     if (!do_fancy_opens) {
  1112.         t = tmpstr->str_ptr;
  1113.         if (*t == '"' || *t == '\'')
  1114.         t = cpytill(tokenbuf,t+1,*t);
  1115.         else
  1116.         fatal("Internal error: OCLOSE %s",t);
  1117.         s = savestr(tokenbuf);
  1118.         for (t = tokenbuf; *t; t++) {
  1119.         *t &= 127;
  1120.         if (islower(*t))
  1121.             *t = toupper(*t);
  1122.         if (!isalpha(*t) && !isdigit(*t))
  1123.             *t = '_';
  1124.         }
  1125.         if (!index(tokenbuf,'_'))
  1126.         strcpy(t,"_FH");
  1127.         str_free(tmpstr);
  1128.         safefree(s);
  1129.         str_set(str,"close ");
  1130.         str_cat(str,tokenbuf);
  1131.     }
  1132.     else {
  1133.         sprintf(tokenbuf,"$fh = delete $opened{%s} && close($fh)",
  1134.            tmpstr->str_ptr);
  1135.         str_free(tmpstr);
  1136.         str_set(str,tokenbuf);
  1137.     }
  1138.     break;
  1139.     case OPRINTF:
  1140.     case OPRINT:
  1141.     lparen = "";    /* set to parens if necessary */
  1142.     rparen = "";
  1143.     str = str_new(0);
  1144.     if (len == 3) {        /* output redirection */
  1145.         tmpstr = walk(1,level,ops[node+3].ival,&numarg,P_MIN);
  1146.         tmp2str = walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  1147.         if (!do_fancy_opens) {
  1148.         t = tmpstr->str_ptr;
  1149.         if (*t == '"' || *t == '\'')
  1150.             t = cpytill(tokenbuf,t+1,*t);
  1151.         else
  1152.             fatal("Internal error: OPRINT");
  1153.         d = savestr(t);
  1154.         s = savestr(tokenbuf);
  1155.         for (t = tokenbuf; *t; t++) {
  1156.             *t &= 127;
  1157.             if (islower(*t))
  1158.             *t = toupper(*t);
  1159.             if (!isalpha(*t) && !isdigit(*t))
  1160.             *t = '_';
  1161.         }
  1162.         if (!index(tokenbuf,'_'))
  1163.             strcpy(t,"_FH");
  1164.         tmp3str = hfetch(symtab,tokenbuf);
  1165.         if (!tmp3str) {
  1166.             str_cat(opens,"open(");
  1167.             str_cat(opens,tokenbuf);
  1168.             str_cat(opens,", ");
  1169.             d[1] = '\0';
  1170.             str_cat(opens,d);
  1171.             str_scat(opens,tmp2str);
  1172.             str_cat(opens,tmpstr->str_ptr+1);
  1173.             if (*tmp2str->str_ptr == '|')
  1174.             str_cat(opens,") || die 'Cannot pipe to \"");
  1175.             else
  1176.             str_cat(opens,") || die 'Cannot create file \"");
  1177.             if (*d == '"')
  1178.             str_cat(opens,"'.\"");
  1179.             str_cat(opens,s);
  1180.             if (*d == '"')
  1181.             str_cat(opens,"\".'");
  1182.             str_cat(opens,"\".';\n");
  1183.             hstore(symtab,tokenbuf,str_make("x"));
  1184.         }
  1185.         str_free(tmpstr);
  1186.         str_free(tmp2str);
  1187.         safefree(s);
  1188.         safefree(d);
  1189.         }
  1190.         else {
  1191.         sprintf(tokenbuf,"&Pick('%s', %s) &&\n",
  1192.            tmp2str->str_ptr, tmpstr->str_ptr);
  1193.         str_cat(str,tokenbuf);
  1194.         tab(str,level+1);
  1195.         strcpy(tokenbuf,"$fh");
  1196.         str_free(tmpstr);
  1197.         str_free(tmp2str);
  1198.         lparen = "(";
  1199.         rparen = ")";
  1200.         }
  1201.     }
  1202.     else
  1203.         strcpy(tokenbuf,"");
  1204.     str_cat(str,lparen);    /* may be null */
  1205.     if (type == OPRINTF)
  1206.         str_cat(str,"printf");
  1207.     else
  1208.         str_cat(str,"print");
  1209.     saw_fh = 0;
  1210.     if (len == 3 || do_fancy_opens) {
  1211.         if (*tokenbuf) {
  1212.         str_cat(str," ");
  1213.         saw_fh = 1;
  1214.         }
  1215.         str_cat(str,tokenbuf);
  1216.     }
  1217.     tmpstr = walk(1+(type==OPRINT),level,ops[node+1].ival,&numarg,P_MIN);
  1218.     if (!*tmpstr->str_ptr && lval_field) {
  1219.         t = saw_OFS ? "$," : "' '";
  1220.         if (split_to_array) {
  1221.         sprintf(tokenbuf,"join(%s,@Fld)",t);
  1222.         str_cat(tmpstr,tokenbuf);
  1223.         }
  1224.         else {
  1225.         for (i = 1; i < maxfld; i++) {
  1226.             if (i <= arymax)
  1227.             sprintf(tokenbuf,"$%s, ",nameary[i]);
  1228.             else
  1229.             sprintf(tokenbuf,"$Fld%d, ",i);
  1230.             str_cat(tmpstr,tokenbuf);
  1231.         }
  1232.         if (maxfld <= arymax)
  1233.             sprintf(tokenbuf,"$%s",nameary[maxfld]);
  1234.         else
  1235.             sprintf(tokenbuf,"$Fld%d",maxfld);
  1236.         str_cat(tmpstr,tokenbuf);
  1237.         }
  1238.     }
  1239.     if (*tmpstr->str_ptr) {
  1240.         str_cat(str," ");
  1241.         if (!saw_fh && *tmpstr->str_ptr == '(') {
  1242.         str_cat(str,"(");
  1243.         str_scat(str,tmpstr);
  1244.         str_cat(str,")");
  1245.         }
  1246.         else
  1247.         str_scat(str,tmpstr);
  1248.     }
  1249.     else {
  1250.         str_cat(str," $_");
  1251.     }
  1252.     str_cat(str,rparen);    /* may be null */
  1253.     str_free(tmpstr);
  1254.     break;
  1255.     case ORAND:
  1256.     str = str_make("rand(1)");
  1257.     break;
  1258.     case OSRAND:
  1259.     str = str_make("srand(");
  1260.     goto maybe0;
  1261.     case OATAN2:
  1262.     str = str_make("atan2(");
  1263.     goto maybe0;
  1264.     case OSIN:
  1265.     str = str_make("sin(");
  1266.     goto maybe0;
  1267.     case OCOS:
  1268.     str = str_make("cos(");
  1269.     goto maybe0;
  1270.     case OSYSTEM:
  1271.     str = str_make("system(");
  1272.     goto maybe0;
  1273.     case OLENGTH:
  1274.     str = str_make("length(");
  1275.     goto maybe0;
  1276.     case OLOG:
  1277.     str = str_make("log(");
  1278.     goto maybe0;
  1279.     case OEXP:
  1280.     str = str_make("exp(");
  1281.     goto maybe0;
  1282.     case OSQRT:
  1283.     str = str_make("sqrt(");
  1284.     goto maybe0;
  1285.     case OINT:
  1286.     str = str_make("int(");
  1287.       maybe0:
  1288.     numeric = 1;
  1289.     if (len > 0)
  1290.         tmpstr = walk(1,level,ops[node+1].ival,&numarg,P_MIN);
  1291.     else
  1292.         tmpstr = str_new(0);;
  1293.     if (!tmpstr->str_ptr || !*tmpstr->str_ptr) {
  1294.         if (lval_field) {
  1295.         t = saw_OFS ? "$," : "' '";
  1296.         if (split_to_array) {
  1297.             sprintf(tokenbuf,"join(%s,@Fld)",t);
  1298.             str_cat(tmpstr,tokenbuf);
  1299.         }
  1300.         else {
  1301.             sprintf(tokenbuf,"join(%s, ",t);
  1302.             str_cat(tmpstr,tokenbuf);
  1303.             for (i = 1; i < maxfld; i++) {
  1304.             if (i <= arymax)
  1305.                 sprintf(tokenbuf,"$%s,",nameary[i]);
  1306.             else
  1307.                 sprintf(tokenbuf,"$Fld%d,",i);
  1308.             str_cat(tmpstr,tokenbuf);
  1309.             }
  1310.             if (maxfld <= arymax)
  1311.             sprintf(tokenbuf,"$%s)",nameary[maxfld]);
  1312.             else
  1313.             sprintf(tokenbuf,"$Fld%d)",maxfld);
  1314.             str_cat(tmpstr,tokenbuf);
  1315.         }
  1316.         }
  1317.         else
  1318.         str_cat(tmpstr,"$_");
  1319.     }
  1320.     if (strEQ(tmpstr->str_ptr,"$_")) {
  1321.         if (type == OLENGTH && !do_chop) {
  1322.         str = str_make("(length(");
  1323.         str_cat(tmpstr,") - 1");
  1324.         }
  1325.     }
  1326.     str_scat(str,tmpstr);
  1327.     str_free(tmpstr);
  1328.     str_cat(str,")");
  1329.     break;
  1330.     case OBREAK:
  1331.     str = str_new(0);
  1332.     str_set(str,"last");
  1333.     break;
  1334.     case ONEXT:
  1335.     str = str_new(0);
  1336.     str_set(str,"next line");
  1337.     break;
  1338.     case OEXIT:
  1339.     str = str_new(0);
  1340.     if (realexit) {
  1341.         prec = P_UNI;
  1342.         str_set(str,"exit");
  1343.         if (len == 1) {
  1344.         str_cat(str," ");
  1345.         exitval = TRUE;
  1346.         str_scat(str,
  1347.           fstr=walk(1,level,ops[node+1].ival,&numarg,prec+1));
  1348.         str_free(fstr);
  1349.         }
  1350.     }
  1351.     else {
  1352.         if (len == 1) {
  1353.         str_set(str,"$ExitValue = ");
  1354.         exitval = TRUE;
  1355.         str_scat(str,
  1356.           fstr=walk(1,level,ops[node+1].ival,&numarg,P_ASSIGN));
  1357.         str_free(fstr);
  1358.         str_cat(str,"; ");
  1359.         }
  1360.         str_cat(str,"last line");
  1361.     }
  1362.     break;
  1363.     case OCONTINUE:
  1364.     str = str_new(0);
  1365.     str_set(str,"next");
  1366.     break;
  1367.     case OREDIR:
  1368.     goto def;
  1369.     case OIF:
  1370.     str = str_new(0);
  1371.     str_set(str,"if (");
  1372.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1373.     str_free(fstr);
  1374.     str_cat(str,") ");
  1375.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1376.     str_free(fstr);
  1377.     if (len == 3) {
  1378.         i = ops[node+3].ival;
  1379.         if (i) {
  1380.         if ((ops[i].ival & 255) == OBLOCK) {
  1381.             i = ops[i+1].ival;
  1382.             if (i) {
  1383.             if ((ops[i].ival & 255) != OIF)
  1384.                 i = 0;
  1385.             }
  1386.         }
  1387.         else
  1388.             i = 0;
  1389.         }
  1390.         if (i) {
  1391.         str_cat(str,"els");
  1392.         str_scat(str,fstr=walk(0,level,i,&numarg,P_MIN));
  1393.         str_free(fstr);
  1394.         }
  1395.         else {
  1396.         str_cat(str,"else ");
  1397.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  1398.         str_free(fstr);
  1399.         }
  1400.     }
  1401.     break;
  1402.     case OWHILE:
  1403.     str = str_new(0);
  1404.     str_set(str,"while (");
  1405.     str_scat(str,fstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1406.     str_free(fstr);
  1407.     str_cat(str,") ");
  1408.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1409.     str_free(fstr);
  1410.     break;
  1411.     case OFOR:
  1412.     str = str_new(0);
  1413.     str_set(str,"for (");
  1414.     str_scat(str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1415.     i = numarg;
  1416.     if (i) {
  1417.         t = s = tmpstr->str_ptr;
  1418.         while (isalpha(*t) || isdigit(*t) || *t == '$' || *t == '_')
  1419.         t++;
  1420.         i = t - s;
  1421.         if (i < 2)
  1422.         i = 0;
  1423.     }
  1424.     str_cat(str,"; ");
  1425.     fstr=walk(1,level,ops[node+2].ival,&numarg,P_MIN);
  1426.     if (i && (t = index(fstr->str_ptr,0377))) {
  1427.         if (strnEQ(fstr->str_ptr,s,i))
  1428.         *t = ' ';
  1429.     }
  1430.     str_scat(str,fstr);
  1431.     str_free(fstr);
  1432.     str_free(tmpstr);
  1433.     str_cat(str,"; ");
  1434.     str_scat(str,fstr=walk(1,level,ops[node+3].ival,&numarg,P_MIN));
  1435.     str_free(fstr);
  1436.     str_cat(str,") ");
  1437.     str_scat(str,fstr=walk(0,level,ops[node+4].ival,&numarg,P_MIN));
  1438.     str_free(fstr);
  1439.     break;
  1440.     case OFORIN:
  1441.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1442.     d = index(tmpstr->str_ptr,'$');
  1443.     if (!d)
  1444.         fatal("Illegal for loop: %s",tmpstr->str_ptr);
  1445.     s = index(d,'{');
  1446.     if (!s)
  1447.         s = index(d,'[');
  1448.     if (!s)
  1449.         fatal("Illegal for loop: %s",d);
  1450.     *s++ = '\0';
  1451.     for (t = s; i = *t; t++) {
  1452.         i &= 127;
  1453.         if (i == '}' || i == ']')
  1454.         break;
  1455.     }
  1456.     if (*t)
  1457.         *t = '\0';
  1458.     str = str_new(0);
  1459.     str_set(str,d+1);
  1460.     str_cat(str,"[]");
  1461.     tmp2str = hfetch(symtab,str->str_ptr);
  1462.     if (tmp2str && atoi(tmp2str->str_ptr)) {
  1463.         sprintf(tokenbuf,
  1464.           "foreach %s ($[ .. $#%s) ",
  1465.           s,
  1466.           d+1);
  1467.     }
  1468.     else {
  1469.         sprintf(tokenbuf,
  1470.           "foreach %s (keys %%%s) ",
  1471.           s,
  1472.           d+1);
  1473.     }
  1474.     str_set(str,tokenbuf);
  1475.     str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1476.     str_free(fstr);
  1477.     str_free(tmpstr);
  1478.     break;
  1479.     case OBLOCK:
  1480.     str = str_new(0);
  1481.     str_set(str,"{");
  1482.     if (len >= 2 && ops[node+2].ival) {
  1483.         str_scat(str,fstr=walk(0,level,ops[node+2].ival,&numarg,P_MIN));
  1484.         str_free(fstr);
  1485.     }
  1486.     fixtab(str,++level);
  1487.     str_scat(str,fstr=walk(0,level,ops[node+1].ival,&numarg,P_MIN));
  1488.     str_free(fstr);
  1489.     addsemi(str);
  1490.     fixtab(str,--level);
  1491.     str_cat(str,"}\n");
  1492.     tab(str,level);
  1493.     if (len >= 3) {
  1494.         str_scat(str,fstr=walk(0,level,ops[node+3].ival,&numarg,P_MIN));
  1495.         str_free(fstr);
  1496.     }
  1497.     break;
  1498.     default:
  1499.       def:
  1500.     if (len) {
  1501.         if (len > 5)
  1502.         fatal("Garbage length in walk");
  1503.         str = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1504.         for (i = 2; i<= len; i++) {
  1505.         str_scat(str,fstr=walk(0,level,ops[node+i].ival,&numarg,P_MIN));
  1506.         str_free(fstr);
  1507.         }
  1508.     }
  1509.     else {
  1510.         str = Nullstr;
  1511.     }
  1512.     break;
  1513.     }
  1514.     if (!str)
  1515.     str = str_new(0);
  1516.  
  1517.     if (useval && prec < minprec) {        /* need parens? */
  1518.     fstr = str_new(str->str_cur+2);
  1519.     str_nset(fstr,"(",1);
  1520.     str_scat(fstr,str);
  1521.     str_ncat(fstr,")",1);
  1522.     str_free(str);
  1523.     str = fstr;
  1524.     }
  1525.  
  1526.     *numericptr = numeric;
  1527. #ifdef DEBUGGING
  1528.     if (debug & 4) {
  1529.     printf("%3d %5d %15s %d %4d ",level,node,opname[type],len,str->str_cur);
  1530.     for (t = str->str_ptr; *t && t - str->str_ptr < 40; t++)
  1531.         if (*t == '\n')
  1532.         printf("\\n");
  1533.         else if (*t == '\t')
  1534.         printf("\\t");
  1535.         else
  1536.         putchar(*t);
  1537.     putchar('\n');
  1538.     }
  1539. #endif
  1540.     return str;
  1541. }
  1542.  
  1543. tab(str,lvl)
  1544. register STR *str;
  1545. register int lvl;
  1546. {
  1547.     while (lvl > 1) {
  1548.     str_cat(str,"\t");
  1549.     lvl -= 2;
  1550.     }
  1551.     if (lvl)
  1552.     str_cat(str,"    ");
  1553. }
  1554.  
  1555. fixtab(str,lvl)
  1556. register STR *str;
  1557. register int lvl;
  1558. {
  1559.     register char *s;
  1560.  
  1561.     /* strip trailing white space */
  1562.  
  1563.     s = str->str_ptr+str->str_cur - 1;
  1564.     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
  1565.     s--;
  1566.     s[1] = '\0';
  1567.     str->str_cur = s + 1 - str->str_ptr;
  1568.     if (s >= str->str_ptr && *s != '\n')
  1569.     str_cat(str,"\n");
  1570.  
  1571.     tab(str,lvl);
  1572. }
  1573.  
  1574. addsemi(str)
  1575. register STR *str;
  1576. {
  1577.     register char *s;
  1578.  
  1579.     s = str->str_ptr+str->str_cur - 1;
  1580.     while (s >= str->str_ptr && (*s == ' ' || *s == '\t' || *s == '\n'))
  1581.     s--;
  1582.     if (s >= str->str_ptr && *s != ';' && *s != '}')
  1583.     str_cat(str,";");
  1584. }
  1585.  
  1586. emit_split(str,level)
  1587. register STR *str;
  1588. int level;
  1589. {
  1590.     register int i;
  1591.  
  1592.     if (split_to_array)
  1593.     str_cat(str,"@Fld");
  1594.     else {
  1595.     str_cat(str,"(");
  1596.     for (i = 1; i < maxfld; i++) {
  1597.         if (i <= arymax)
  1598.         sprintf(tokenbuf,"$%s,",nameary[i]);
  1599.         else
  1600.         sprintf(tokenbuf,"$Fld%d,",i);
  1601.         str_cat(str,tokenbuf);
  1602.     }
  1603.     if (maxfld <= arymax)
  1604.         sprintf(tokenbuf,"$%s)",nameary[maxfld]);
  1605.     else
  1606.         sprintf(tokenbuf,"$Fld%d)",maxfld);
  1607.     str_cat(str,tokenbuf);
  1608.     }
  1609.     if (const_FS) {
  1610.     sprintf(tokenbuf," = split(/[%c\\n]/, $_, 9999);\n",const_FS);
  1611.     str_cat(str,tokenbuf);
  1612.     }
  1613.     else if (saw_FS)
  1614.     str_cat(str," = split($FS, $_, 9999);\n");
  1615.     else
  1616.     str_cat(str," = split(' ', $_, 9999);\n");
  1617.     tab(str,level);
  1618. }
  1619.  
  1620. prewalk(numit,level,node,numericptr)
  1621. int numit;
  1622. int level;
  1623. register int node;
  1624. int *numericptr;
  1625. {
  1626.     register int len;
  1627.     register int type;
  1628.     register int i;
  1629.     char *t;
  1630.     char *d, *s;
  1631.     int numarg;
  1632.     int numeric = FALSE;
  1633.     STR *tmpstr;
  1634.     STR *tmp2str;
  1635.  
  1636.     if (!node) {
  1637.     *numericptr = 0;
  1638.     return 0;
  1639.     }
  1640.     type = ops[node].ival;
  1641.     len = type >> 8;
  1642.     type &= 255;
  1643.     switch (type) {
  1644.     case OPROG:
  1645.     prewalk(0,level,ops[node+1].ival,&numarg);
  1646.     if (ops[node+2].ival) {
  1647.         prewalk(0,level,ops[node+2].ival,&numarg);
  1648.     }
  1649.     ++level;
  1650.     prewalk(0,level,ops[node+3].ival,&numarg);
  1651.     --level;
  1652.     if (ops[node+3].ival) {
  1653.         prewalk(0,level,ops[node+4].ival,&numarg);
  1654.     }
  1655.     break;
  1656.     case OHUNKS:
  1657.     prewalk(0,level,ops[node+1].ival,&numarg);
  1658.     prewalk(0,level,ops[node+2].ival,&numarg);
  1659.     if (len == 3) {
  1660.         prewalk(0,level,ops[node+3].ival,&numarg);
  1661.     }
  1662.     break;
  1663.     case ORANGE:
  1664.     prewalk(1,level,ops[node+1].ival,&numarg);
  1665.     prewalk(1,level,ops[node+2].ival,&numarg);
  1666.     break;
  1667.     case OPAT:
  1668.     goto def;
  1669.     case OREGEX:
  1670.     prewalk(0,level,ops[node+1].ival,&numarg);
  1671.     break;
  1672.     case OHUNK:
  1673.     if (len == 1) {
  1674.         prewalk(0,level,ops[node+1].ival,&numarg);
  1675.     }
  1676.     else {
  1677.         i = prewalk(0,level,ops[node+1].ival,&numarg);
  1678.         if (i) {
  1679.         ++level;
  1680.         prewalk(0,level,ops[node+2].ival,&numarg);
  1681.         --level;
  1682.         }
  1683.         else {
  1684.         prewalk(0,level,ops[node+2].ival,&numarg);
  1685.         }
  1686.     }
  1687.     break;
  1688.     case OPPAREN:
  1689.     prewalk(0,level,ops[node+1].ival,&numarg);
  1690.     break;
  1691.     case OPANDAND:
  1692.     prewalk(0,level,ops[node+1].ival,&numarg);
  1693.     prewalk(0,level,ops[node+2].ival,&numarg);
  1694.     break;
  1695.     case OPOROR:
  1696.     prewalk(0,level,ops[node+1].ival,&numarg);
  1697.     prewalk(0,level,ops[node+2].ival,&numarg);
  1698.     break;
  1699.     case OPNOT:
  1700.     prewalk(0,level,ops[node+1].ival,&numarg);
  1701.     break;
  1702.     case OCPAREN:
  1703.     prewalk(0,level,ops[node+1].ival,&numarg);
  1704.     numeric |= numarg;
  1705.     break;
  1706.     case OCANDAND:
  1707.     prewalk(0,level,ops[node+1].ival,&numarg);
  1708.     numeric = 1;
  1709.     prewalk(0,level,ops[node+2].ival,&numarg);
  1710.     break;
  1711.     case OCOROR:
  1712.     prewalk(0,level,ops[node+1].ival,&numarg);
  1713.     numeric = 1;
  1714.     prewalk(0,level,ops[node+2].ival,&numarg);
  1715.     break;
  1716.     case OCNOT:
  1717.     prewalk(0,level,ops[node+1].ival,&numarg);
  1718.     numeric = 1;
  1719.     break;
  1720.     case ORELOP:
  1721.     prewalk(0,level,ops[node+2].ival,&numarg);
  1722.     numeric |= numarg;
  1723.     prewalk(0,level,ops[node+1].ival,&numarg);
  1724.     prewalk(0,level,ops[node+3].ival,&numarg);
  1725.     numeric |= numarg;
  1726.     numeric = 1;
  1727.     break;
  1728.     case ORPAREN:
  1729.     prewalk(0,level,ops[node+1].ival,&numarg);
  1730.     numeric |= numarg;
  1731.     break;
  1732.     case OMATCHOP:
  1733.     prewalk(0,level,ops[node+2].ival,&numarg);
  1734.     prewalk(0,level,ops[node+1].ival,&numarg);
  1735.     prewalk(0,level,ops[node+3].ival,&numarg);
  1736.     numeric = 1;
  1737.     break;
  1738.     case OMPAREN:
  1739.     prewalk(0,level,ops[node+1].ival,&numarg);
  1740.     numeric |= numarg;
  1741.     break;
  1742.     case OCONCAT:
  1743.     prewalk(0,level,ops[node+1].ival,&numarg);
  1744.     prewalk(0,level,ops[node+2].ival,&numarg);
  1745.     break;
  1746.     case OASSIGN:
  1747.     prewalk(0,level,ops[node+2].ival,&numarg);
  1748.     prewalk(0,level,ops[node+1].ival,&numarg);
  1749.     prewalk(0,level,ops[node+3].ival,&numarg);
  1750.     if (numarg || strlen(ops[ops[node+1].ival+1].cval) > 1) {
  1751.         numericize(ops[node+2].ival);
  1752.         if (!numarg)
  1753.         numericize(ops[node+3].ival);
  1754.     }
  1755.     numeric |= numarg;
  1756.     break;
  1757.     case OADD:
  1758.     prewalk(1,level,ops[node+1].ival,&numarg);
  1759.     prewalk(1,level,ops[node+2].ival,&numarg);
  1760.     numeric = 1;
  1761.     break;
  1762.     case OSUBTRACT:
  1763.     prewalk(1,level,ops[node+1].ival,&numarg);
  1764.     prewalk(1,level,ops[node+2].ival,&numarg);
  1765.     numeric = 1;
  1766.     break;
  1767.     case OMULT:
  1768.     prewalk(1,level,ops[node+1].ival,&numarg);
  1769.     prewalk(1,level,ops[node+2].ival,&numarg);
  1770.     numeric = 1;
  1771.     break;
  1772.     case ODIV:
  1773.     prewalk(1,level,ops[node+1].ival,&numarg);
  1774.     prewalk(1,level,ops[node+2].ival,&numarg);
  1775.     numeric = 1;
  1776.     break;
  1777.     case OPOW:
  1778.     prewalk(1,level,ops[node+1].ival,&numarg);
  1779.     prewalk(1,level,ops[node+2].ival,&numarg);
  1780.     numeric = 1;
  1781.     break;
  1782.     case OMOD:
  1783.     prewalk(1,level,ops[node+1].ival,&numarg);
  1784.     prewalk(1,level,ops[node+2].ival,&numarg);
  1785.     numeric = 1;
  1786.     break;
  1787.     case OPOSTINCR:
  1788.     prewalk(1,level,ops[node+1].ival,&numarg);
  1789.     numeric = 1;
  1790.     break;
  1791.     case OPOSTDECR:
  1792.     prewalk(1,level,ops[node+1].ival,&numarg);
  1793.     numeric = 1;
  1794.     break;
  1795.     case OPREINCR:
  1796.     prewalk(1,level,ops[node+1].ival,&numarg);
  1797.     numeric = 1;
  1798.     break;
  1799.     case OPREDECR:
  1800.     prewalk(1,level,ops[node+1].ival,&numarg);
  1801.     numeric = 1;
  1802.     break;
  1803.     case OUMINUS:
  1804.     prewalk(1,level,ops[node+1].ival,&numarg);
  1805.     numeric = 1;
  1806.     break;
  1807.     case OUPLUS:
  1808.     prewalk(1,level,ops[node+1].ival,&numarg);
  1809.     numeric = 1;
  1810.     break;
  1811.     case OPAREN:
  1812.     prewalk(0,level,ops[node+1].ival,&numarg);
  1813.     numeric |= numarg;
  1814.     break;
  1815.     case OGETLINE:
  1816.     break;
  1817.     case OSPRINTF:
  1818.     prewalk(0,level,ops[node+1].ival,&numarg);
  1819.     break;
  1820.     case OSUBSTR:
  1821.     prewalk(0,level,ops[node+1].ival,&numarg);
  1822.     prewalk(1,level,ops[node+2].ival,&numarg);
  1823.     if (len == 3) {
  1824.         prewalk(1,level,ops[node+3].ival,&numarg);
  1825.     }
  1826.     break;
  1827.     case OSTRING:
  1828.     break;
  1829.     case OSPLIT:
  1830.     numeric = 1;
  1831.     prewalk(0,level,ops[node+2].ival,&numarg);
  1832.     if (len == 3)
  1833.         prewalk(0,level,ops[node+3].ival,&numarg);
  1834.     prewalk(0,level,ops[node+1].ival,&numarg);
  1835.     break;
  1836.     case OINDEX:
  1837.     prewalk(0,level,ops[node+1].ival,&numarg);
  1838.     prewalk(0,level,ops[node+2].ival,&numarg);
  1839.     numeric = 1;
  1840.     break;
  1841.     case OMATCH:
  1842.     prewalk(0,level,ops[node+1].ival,&numarg);
  1843.     prewalk(0,level,ops[node+2].ival,&numarg);
  1844.     numeric = 1;
  1845.     break;
  1846.     case OUSERDEF:
  1847.     subretnum = FALSE;
  1848.     --level;
  1849.     tmpstr = walk(0,level,ops[node+1].ival,&numarg,P_MIN);
  1850.     ++level;
  1851.     prewalk(0,level,ops[node+2].ival,&numarg);
  1852.     prewalk(0,level,ops[node+4].ival,&numarg);
  1853.     prewalk(0,level,ops[node+5].ival,&numarg);
  1854.     --level;
  1855.     str_cat(tmpstr,"(");
  1856.     tmp2str = str_new(0);
  1857.     if (subretnum || numarg)
  1858.         str_set(tmp2str,"1");
  1859.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  1860.     str_free(tmpstr);
  1861.     level++;
  1862.     break;
  1863.     case ORETURN:
  1864.     if (len > 0) {
  1865.         prewalk(0,level,ops[node+1].ival,&numarg);
  1866.         if (numarg)
  1867.         subretnum = TRUE;
  1868.     }
  1869.     break;
  1870.     case OUSERFUN:
  1871.     tmp2str = str_new(0);
  1872.     str_scat(tmp2str,tmpstr=walk(1,level,ops[node+1].ival,&numarg,P_MIN));
  1873.     fixrargs(tmpstr->str_ptr,ops[node+2].ival,0);
  1874.     str_free(tmpstr);
  1875.     str_cat(tmp2str,"(");
  1876.     tmpstr = hfetch(symtab,tmp2str->str_ptr);
  1877.     if (tmpstr && tmpstr->str_ptr)
  1878.         numeric |= atoi(tmpstr->str_ptr);
  1879.     prewalk(0,level,ops[node+2].ival,&numarg);
  1880.     str_free(tmp2str);
  1881.     break;
  1882.     case OGSUB:
  1883.     case OSUB:
  1884.     if (len >= 3)
  1885.         prewalk(0,level,ops[node+3].ival,&numarg);
  1886.     prewalk(0,level,ops[ops[node+2].ival+1].ival,&numarg);
  1887.     prewalk(0,level,ops[node+1].ival,&numarg);
  1888.     numeric = 1;
  1889.     break;
  1890.     case ONUM:
  1891.     prewalk(0,level,ops[node+1].ival,&numarg);
  1892.     numeric = 1;
  1893.     break;
  1894.     case OSTR:
  1895.     prewalk(0,level,ops[node+1].ival,&numarg);
  1896.     break;
  1897.     case ODEFINED:
  1898.     case ODELETE:
  1899.     case OSTAR:
  1900.     case OVAR:
  1901.     prewalk(0,level,ops[node+1].ival,&numarg);
  1902.     if (len == 1) {
  1903.         if (numit)
  1904.         numericize(node);
  1905.     }
  1906.     else {
  1907.         prewalk(0,level,ops[node+2].ival,&numarg);
  1908.     }
  1909.     break;
  1910.     case OFLD:
  1911.     prewalk(0,level,ops[node+1].ival,&numarg);
  1912.     break;
  1913.     case OVFLD:
  1914.     i = ops[node+1].ival;
  1915.     prewalk(0,level,i,&numarg);
  1916.     break;
  1917.     case OJUNK:
  1918.     goto def;
  1919.     case OSNEWLINE:
  1920.     break;
  1921.     case ONEWLINE:
  1922.     break;
  1923.     case OSCOMMENT:
  1924.     break;
  1925.     case OCOMMENT:
  1926.     break;
  1927.     case OCOMMA:
  1928.     prewalk(0,level,ops[node+1].ival,&numarg);
  1929.     prewalk(0,level,ops[node+2].ival,&numarg);
  1930.     prewalk(0,level,ops[node+3].ival,&numarg);
  1931.     break;
  1932.     case OSEMICOLON:
  1933.     break;
  1934.     case OSTATES:
  1935.     prewalk(0,level,ops[node+1].ival,&numarg);
  1936.     prewalk(0,level,ops[node+2].ival,&numarg);
  1937.     break;
  1938.     case OSTATE:
  1939.     if (len >= 1) {
  1940.         prewalk(0,level,ops[node+1].ival,&numarg);
  1941.         if (len >= 2) {
  1942.         prewalk(0,level,ops[node+2].ival,&numarg);
  1943.         }
  1944.     }
  1945.     break;
  1946.     case OCLOSE:
  1947.     prewalk(0,level,ops[node+1].ival,&numarg);
  1948.     break;
  1949.     case OPRINTF:
  1950.     case OPRINT:
  1951.     if (len == 3) {        /* output redirection */
  1952.         prewalk(0,level,ops[node+3].ival,&numarg);
  1953.         prewalk(0,level,ops[node+2].ival,&numarg);
  1954.     }
  1955.     prewalk(0+(type==OPRINT),level,ops[node+1].ival,&numarg);
  1956.     break;
  1957.     case ORAND:
  1958.     break;
  1959.     case OSRAND:
  1960.     goto maybe0;
  1961.     case OATAN2:
  1962.     goto maybe0;
  1963.     case OSIN:
  1964.     goto maybe0;
  1965.     case OCOS:
  1966.     goto maybe0;
  1967.     case OSYSTEM:
  1968.     goto maybe0;
  1969.     case OLENGTH:
  1970.     goto maybe0;
  1971.     case OLOG:
  1972.     goto maybe0;
  1973.     case OEXP:
  1974.     goto maybe0;
  1975.     case OSQRT:
  1976.     goto maybe0;
  1977.     case OINT:
  1978.       maybe0:
  1979.     numeric = 1;
  1980.     if (len > 0)
  1981.         prewalk(type != OLENGTH && type != OSYSTEM,
  1982.           level,ops[node+1].ival,&numarg);
  1983.     break;
  1984.     case OBREAK:
  1985.     break;
  1986.     case ONEXT:
  1987.     break;
  1988.     case OEXIT:
  1989.     if (len == 1) {
  1990.         prewalk(1,level,ops[node+1].ival,&numarg);
  1991.     }
  1992.     break;
  1993.     case OCONTINUE:
  1994.     break;
  1995.     case OREDIR:
  1996.     goto def;
  1997.     case OIF:
  1998.     prewalk(0,level,ops[node+1].ival,&numarg);
  1999.     prewalk(0,level,ops[node+2].ival,&numarg);
  2000.     if (len == 3) {
  2001.         prewalk(0,level,ops[node+3].ival,&numarg);
  2002.     }
  2003.     break;
  2004.     case OWHILE:
  2005.     prewalk(0,level,ops[node+1].ival,&numarg);
  2006.     prewalk(0,level,ops[node+2].ival,&numarg);
  2007.     break;
  2008.     case OFOR:
  2009.     prewalk(0,level,ops[node+1].ival,&numarg);
  2010.     prewalk(0,level,ops[node+2].ival,&numarg);
  2011.     prewalk(0,level,ops[node+3].ival,&numarg);
  2012.     prewalk(0,level,ops[node+4].ival,&numarg);
  2013.     break;
  2014.     case OFORIN:
  2015.     prewalk(0,level,ops[node+2].ival,&numarg);
  2016.     prewalk(0,level,ops[node+1].ival,&numarg);
  2017.     break;
  2018.     case OBLOCK:
  2019.     if (len == 2) {
  2020.         prewalk(0,level,ops[node+2].ival,&numarg);
  2021.     }
  2022.     ++level;
  2023.     prewalk(0,level,ops[node+1].ival,&numarg);
  2024.     --level;
  2025.     break;
  2026.     default:
  2027.       def:
  2028.     if (len) {
  2029.         if (len > 5)
  2030.         fatal("Garbage length in prewalk");
  2031.         prewalk(0,level,ops[node+1].ival,&numarg);
  2032.         for (i = 2; i<= len; i++) {
  2033.         prewalk(0,level,ops[node+i].ival,&numarg);
  2034.         }
  2035.     }
  2036.     break;
  2037.     }
  2038.     *numericptr = numeric;
  2039.     return 1;
  2040. }
  2041.  
  2042. numericize(node)
  2043. register int node;
  2044. {
  2045.     register int len;
  2046.     register int type;
  2047.     register int i;
  2048.     STR *tmpstr;
  2049.     STR *tmp2str;
  2050.     int numarg;
  2051.  
  2052.     type = ops[node].ival;
  2053.     len = type >> 8;
  2054.     type &= 255;
  2055.     if (type == OVAR && len == 1) {
  2056.     tmpstr=walk(0,0,ops[node+1].ival,&numarg,P_MIN);
  2057.     tmp2str = str_make("1");
  2058.     hstore(symtab,tmpstr->str_ptr,tmp2str);
  2059.     }
  2060. }
  2061.